import time
import docker
from typing import List, Dict
import logging

# 配置日志
logger = logging.getLogger(__name__)

class MirrorDetector:
    """
    Docker镜像加速器检测器
    负责检测各种镜像加速器的有效性
    """
    
    # 常见的Docker镜像加速器地址
    DEFAULT_MIRRORS = [
        "https://docker.mirrors.ustc.edu.cn",
        "https://hub-mirror.c.163.com",
        "https://mirror.ccs.tencentyun.com",
        "https://registry.docker-cn.com"
    ]
    
    # 测试镜像
    TEST_IMAGE = "hello-world:latest"
    
    def __init__(self, mirrors: List[str] = None):
        """
        初始化镜像检测器
        
        Args:
            mirrors: 镜像加速器列表，如果未提供则使用默认列表
        """
        self.mirrors = mirrors if mirrors is not None else self.DEFAULT_MIRRORS
        try:
            self.client = docker.from_env()
        except Exception as e:
            logger.error(f"无法连接到Docker守护进程: {e}")
            raise RuntimeError("无法连接到Docker守护进程，请确保Docker已启动")
    
    def test_mirror(self, mirror_url: str, timeout: int = 30) -> Dict:
        """
        测试单个镜像加速器的有效性
        
        Args:
            mirror_url: 镜像加速器URL
            timeout: 拉取镜像超时时间（秒）
            
        Returns:
            包含测试结果的字典
        """
        logger.info(f"Testing mirror: {mirror_url}")
        
        start_time = time.time()
        result = {
            "mirror_url": mirror_url,
            "is_valid": False,
            "response_time": None,
            "error_message": None
        }
        
        # 构造带镜像加速器的镜像名
        if mirror_url.endswith('/'):
            full_image_name = f"{mirror_url}{self.TEST_IMAGE}"
        else:
            full_image_name = f"{mirror_url}/{self.TEST_IMAGE}"
            
        try:
            # 尝试拉取镜像
            self.client.images.pull(full_image_name, timeout=timeout)
            end_time = time.time()
            
            result["response_time"] = round(end_time - start_time, 3)
            result["is_valid"] = True
            
            # 清理拉取的镜像
            try:
                self.client.images.remove(full_image_name, force=True)
            except:
                pass
                
        except docker.errors.ImageNotFound:
            end_time = time.time()
            result["response_time"] = round(end_time - start_time, 3)
            result["error_message"] = "Image not found"
        except docker.errors.APIError as e:
            end_time = time.time()
            result["response_time"] = round(end_time - start_time, 3)
            result["error_message"] = f"Docker API error: {str(e)[:100]}"
        except Exception as e:
            end_time = time.time()
            result["response_time"] = round(end_time - start_time, 3)
            result["error_message"] = f"Unexpected error: {str(e)[:100]}"
            
        logger.info(f"Test result for {mirror_url}: valid={result['is_valid']}")
        return result
    
    def test_all_mirrors(self, timeout: int = 30) -> List[Dict]:
        """
        测试所有镜像加速器
        
        Args:
            timeout: 拉取镜像超时时间（秒）
            
        Returns:
            所有镜像加速器的测试结果列表
        """
        results = []
        for mirror in self.mirrors:
            result = self.test_mirror(mirror, timeout)
            results.append(result)
        return results